package com.zt.chatgpt.openai.service.rule.impl;

import com.google.common.cache.Cache;
import com.zt.chatgpt.openai.annotation.LogicStrategy;
import com.zt.chatgpt.openai.model.aggregates.ChatProcessAggregate;
import com.zt.chatgpt.openai.model.aggregates.UserAccountQuotaEntity;
import com.zt.chatgpt.openai.model.entity.RuleLogicEntity;
import com.zt.chatgpt.openai.model.valobj.LogicCheckTypeVO;
import com.zt.chatgpt.openai.service.rule.ILogicFilter;
import com.zt.chatgpt.openai.service.rule.factory.DefaultLogicFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author: zt
 * @Description: 访问频率限制过滤器
 * @create: 2024-05-21 23:07
 */
@Slf4j
@Component
@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.ACCESS_LIMIT)
public class AccessLimitFilter implements ILogicFilter<UserAccountQuotaEntity> {

    @Value("${app.config.limit-count}")
    private Integer limitCount;

    @Value("${app.config.white-list}")
    private String whiteListStr;

    @Resource
    private Cache<String, Integer> visitCache;


    @Override
    public RuleLogicEntity<ChatProcessAggregate> filter(ChatProcessAggregate chatProcessAggregate, UserAccountQuotaEntity data) throws Exception {
        // 1. 白名单放行
        if (chatProcessAggregate.isWhiteList(whiteListStr)) {
            return RuleLogicEntity.<ChatProcessAggregate>builder()
                    .type(LogicCheckTypeVO.SUCCESS)
                    .data(chatProcessAggregate)
                    .info("白名单放行")
                    .build();
        }
        // 2. 用户个人账户不为空，直接放行
        if (null != data) {
            return RuleLogicEntity.<ChatProcessAggregate>builder()
                    .type(LogicCheckTypeVO.SUCCESS)
                    .data(chatProcessAggregate)
                    .info("用户个人账户不为空，直接放行")
                    .build();
        }

        // 下面是针对未购买额度的用户
        // 3. 访问次数判断
        String openId = chatProcessAggregate.getOpenId();
        int visitCount = visitCache.get(openId, () -> 0);
        if (visitCount < limitCount) {
            visitCache.put(openId, visitCount + 1);
            return RuleLogicEntity.<ChatProcessAggregate>builder()
                    .type(LogicCheckTypeVO.SUCCESS)
                    .data(chatProcessAggregate)
                    .info("访问次数限制通过")
                    .build();
        }
        // 4. 访问次数不足
        return RuleLogicEntity.<ChatProcessAggregate>builder()
                .type(LogicCheckTypeVO.REFUSE)
                .data(chatProcessAggregate)
                .info("您今日的免费" + limitCount + "次，已耗尽！")
                .build();
    }
}
